#include <stddef.h>
#include <stdio.h>
#include <inttypes.h>
#include "Utils.h"
#include "driver/gpio.h"
#include "drivers/fingerprint.h"
#include "drivers/keyboard.h"
#include "drivers/led.h"
#include "drivers/motor.h"
#include "drivers/wtn_audio.h"
#include "drivers/led.c"
#include "drivers/bluetooth.h"
#include "drivers/temp_password.h"
#include "drivers/WIFI.h"
#include "drivers/scan.h"
#include "freertos/FreeRTOS.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include <esp_system.h> // 包含 esp_random()
#include <string.h>

/// 输入次数
static int input_count = 0;
/// 保存输入的案件值
static uint8_t password_arry[7] = {0};

/// 是否要录入指纹 1：是 0：否
static int is_add_fingerprint = 0;
/// 是否有手指在指纹模块上
static int is_fingerprint_on = 0;
static int is_add_password = 0;

static QueueHandle_t gpio_event_queue = NULL;

// 静态函数，用于处理GPIO中断
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    // 获取GPIO引脚号
    uint32_t gpio_num = (uint32_t) arg;

    // 检查是否是指纹模块的中断
    // 如果是禁用掉其他中断
    // 同时设置标志位
    if(gpio_num == FINGERPRINT_TOUCH_INT)
    {
        // if(is_add_fingerprint == 1){
        //     gpio_isr_handler_remove(FINGERPRINT_TOUCH_INT);
        //     gpio_isr_handler_remove(KEYBOARD_INT);
        // }
        gpio_isr_handler_remove(FINGERPRINT_TOUCH_INT);
        gpio_isr_handler_remove(KEYBOARD_INT);
        is_fingerprint_on = 1;
    }
    // 将GPIO引脚号发送到队列中
    xQueueSendFromISR(gpio_event_queue, &gpio_num, NULL);
}

static void identify_fingerprint_task(void* arg)
{
    while(1)
    {
        if(!is_add_fingerprint && is_fingerprint_on)
        {
            printf("识别指纹\r\n");
            if(Fingerprint_Identify()){
                printf("指纹验证失败\r\n");
            } else {
                motor_open_lock();
                // 播放语音提示
                wtn_audio_play(0xef);
                wtn_audio_play(0x01);
                printf("指纹验证成功\r\n");
                
            }
            is_fingerprint_on = 0;
            Fingerprint_Cancel();
            Fingerprint_Sleep(); // 睡眠
            gpio_isr_handler_add(FINGERPRINT_TOUCH_INT, gpio_isr_handler, (void*)FINGERPRINT_TOUCH_INT);
            gpio_isr_handler_add(KEYBOARD_INT, gpio_isr_handler, (void*)KEYBOARD_INT);
        }
        DelayMs(20); // 延时200ms
    }
}

/// 录入指纹的任务
static void enroll_fingerprint_task(void* arg)
{
    while (1) {
        if(is_add_fingerprint)
        {
            printf("录入指纹\r\n");
            // 播放语音提示
            wtn_audio_play(0xef);
            wtn_audio_play(0x02);
            // 轮询直到有手指按在指纹模块上
            while(!is_fingerprint_on)
            {
                DelayMs(100);
            }
            // 获取已经存储的指纹数量
            uint8_t count = Fingerprint_GetTemplatesCount();
            Fingerprint_Enroll(count+1);
            is_fingerprint_on = 0;
            is_add_fingerprint = 0;
            Fingerprint_Cancel();
            Fingerprint_Sleep(); // 睡眠
            gpio_isr_handler_add(FINGERPRINT_TOUCH_INT, gpio_isr_handler, (void*)FINGERPRINT_TOUCH_INT);
            gpio_isr_handler_add(KEYBOARD_INT, gpio_isr_handler, (void*)KEYBOARD_INT);
        }
        DelayMs(200); // 延时200ms
    }
}

static void gpio_task(void* arg)
{
    UBaseType_t stack_remain = uxTaskGetStackHighWaterMark(NULL);
    ESP_LOGI("GPIO", "剩余栈空间: %u bytes", stack_remain);
    // 从队列中接收GPIO引脚号
    uint32_t gpio_num;
    while (1)
    {
        if (xQueueReceive(gpio_event_queue, &gpio_num, portMAX_DELAY))
        {
            // 处理GPIO事件
            // printf("GPIO %ld triggered!\n", gpio_num);
            if(gpio_num == KEYBOARD_INT)
            {
                
                uint8_t key = KEYBOARD_ReadKey();
                static uint8_t cmd = 0;
                if(key!=0xff){
                    printf("pressed key = %c \r\n", key);
                    printf("cmd = %d \r\n", cmd);
                    wtn_audio_play(cmd++);
                    wtn_audio_play(0x0b);
                    wtn_audio_play(0x11);
                    // printf("开锁开启");
                    // motor_open_lock();
                    srand(xTaskGetTickCount());  // 初始化随机种子
                    uint8_t r = rand() % 256;  // 生成随机数
                    uint8_t g = rand() % 256;  // 生成随机数
                    uint8_t b = rand() % 256;  // 生成随机数
                    LED_Light(0, r, g, b);
                    /// 将按键值保存到数组中
                    password_arry[input_count] = key;
                    input_count++;
                    /// 连续按下3次A进入录入指纹模式
                    if(input_count >= 3 && password_arry[input_count-1] == 'A' && 
                        password_arry[input_count-2] == 'A' && password_arry[input_count-3] == 'A')
                        {
                            input_count = 0;
                            memset(password_arry, 0, sizeof(password_arry));
                            is_add_fingerprint = 1;
                        }
                    if(input_count >= 4 && password_arry[input_count-1] == 'A' && password_arry[input_count-2] == 'B' && password_arry[input_count-3] == 'C' && password_arry[input_count-4] == '#')
                    {
                        input_count = 0;
                        is_add_password = 1;
                        memset(password_arry, 0, sizeof(password_arry));
                        printf("添加密码\r\n");
                    }

                    if(input_count == 6 && !is_add_password){
                        input_count = 0;
                        password_arry[-1] = '\0';
                        printf("密码输入完成\r\n");
                        nvs_handle_t getPWD_handle;
                        uint8_t temp_password_arry[7] = {0};
                        size_t length = sizeof(temp_password_arry);
                        nvs_open("password", NVS_READWRITE, &getPWD_handle);
                        nvs_get_str(getPWD_handle, "password", (char*)temp_password_arry,&length);
                        nvs_close(getPWD_handle);
                        printf("temp_password_arry = %s", temp_password_arry);
                        printf("password_arry = %s", password_arry);
                        if(memcmp(password_arry, temp_password_arry, sizeof(password_arry)) == 0){
                            motor_open_lock();
                            // 播放语音提示
                            wtn_audio_play(0xef);
                            wtn_audio_play(0x01);
                        } else if ((PASSWORD_ValidateTempPassword(password_arry))){
                            motor_open_lock();
                            // 播放语音提示
                            wtn_audio_play(0xef);
                            wtn_audio_play(0x01);
                        }
                        else {
                            printf("密码错误\r\n");
                            wtn_audio_play(0xef);
                            wtn_audio_play(0x03);
                        }
                        memset(password_arry, 0, sizeof(password_arry));
                    }
                    if (input_count == 6 && is_add_password ) {
                        input_count = 0;
                        nvs_handle_t addPWD_handle;
                        password_arry[input_count-1] = '\0';
                        nvs_open("password", NVS_READWRITE, &addPWD_handle);
                        nvs_set_str(addPWD_handle, "password", (char*)password_arry);
                        nvs_commit(addPWD_handle);
                        nvs_close(addPWD_handle);
                        is_add_password = 0;
                        memset(password_arry, 0, sizeof(password_arry));
                        printf("密码添加成功");
                    }

                    if(password_arry[input_count-1] == '*'){
                        input_count = 0;
                    }
                    // printf("input_count = %d \r\n", input_count);
                    printf("\r\n");
                }
            }
            else if(gpio_num == FINGERPRINT_TOUCH_INT)
            {
                printf("指纹传感器被按下！\r\n");
                wtn_audio_play(0xef);
                wtn_audio_play(0x01);
                is_fingerprint_on = 1;
            }
        }
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
    
}

// 静态函数，用于初始化队列
static void ISR_QUEUE_Init(void)
{
    // 创建一个队列，队列长度为10，每个元素大小为uint32_t
    gpio_event_queue = xQueueCreate(10, sizeof(uint32_t));
    // 创建一个任务，任务名为gpio_task，任务堆栈大小为2048，任务优先级为10
    xTaskCreate(gpio_task, "gpio_task", 4096, NULL, 10, NULL);
    // 创建一个任务，任务名为gpio_task，任务堆栈大小为2048，任务优先级为10
    xTaskCreate(enroll_fingerprint_task, "enroll_fingerprint_task", 4096, NULL, 10, NULL);
    // 安装GPIO中断服务  启用中断服务
    xTaskCreate(identify_fingerprint_task, "identify_fingerprint_task", 4096, NULL, 10, NULL);
    gpio_install_isr_service(0);
    // 添加GPIO中断处理函数，中断号为KEYBOARD_INT，处理函数为gpio_isr_handler，参数为(void*) KEYBOARD_INT
    gpio_isr_handler_add(KEYBOARD_INT, gpio_isr_handler, (void*) KEYBOARD_INT);
    gpio_isr_handler_add(FINGERPRINT_TOUCH_INT, gpio_isr_handler, (void*) FINGERPRINT_TOUCH_INT);
}



void app_main(void)
{
    esp_err_t ret;
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );
    Fingerprint_Init();
    KEYBOARD_Init();
    motor_init();
    wtn_audio_init();
    LED_Init();
    printf("Hello World\r\n");
    printf("Hello World\r\n");
    Fingerprint_GetSerialNumber();
    Fingerprint_GetTemplatesCount();
    Fingerprint_SetSecurityLevel(0);
    Fingerprint_Cancel();
    Fingerprint_Sleep();
    ISR_QUEUE_Init();
    bluetooth_init();
    WIFI_Init();
    wifi_scan_init();

    
    // printf("Hello World\r\n");
    // printf("Hello World\r\n");
    // Fingerprint_GetSerialNumber();
    // Fingerprint_GetTemplatesCount();
    // Fingerprint_SetSecurityLevel(0);
    // Fingerprint_Cancel();
    // Fingerprint_Sleep();
    
    


    while (1)
    {
        // printf("Hello World\r\n");
        // printf("Hello World\r\n");
        // Fingerprint_GetSerialNumber();
        // Fingerprint_GetTemplatesCount();
        // Fingerprint_SetSecurityLevel(0);
        // Fingerprint_Cancel();
        // Fingerprint_Sleep();

        
       
        time_t now;
        time(&now); // 获取当前时间
        printf("%" PRIu64 "\n", now);
        
        vTaskDelay(10000 / portTICK_PERIOD_MS);
    }
    
}



